home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programmierung
/
Power-Programmierung (Tewi)(1994).iso
/
magazine
/
msysjour
/
vol06
/
04
/
timer
/
tick.asm
next >
Wrap
Assembly Source File
|
1991-07-01
|
5KB
|
134 lines
;*****************************************************************************
;
; A GetTickCount() that is accurate to the millisecond
;
; Copyright (C) 1988-1991 Datametrics Systems Corporation
;
; Notes:
;
; - Proc directly accesses the 8254 timer chip (does port I/O).
; - Proc issues sti/cli instructions.
; - Assumes timer interrupt frequency has not been changed.
; - There is a dramatic performance degradation if this proc
; is executed on a 386 w/ I/O port trapping enabled for the
; timer chip.
; - Time will wrap after 49.7 days (1ms) or 4.97 days (100us).
; - TIMERRES is 54925, the interrupt period in microseconds.
;
;*****************************************************************************
TENTHTICK EQU 0
if (TENTHTICK)
TR1 EQU 16384 ;; (WORD)((TIMERRES*10*65536)/1000)
TR2 EQU 549 ;; (TIMERRES*10/1000)
TR3 EQU 8788 ;; (TIMERRES*10*16)/1000
else
TR1 EQU 60620 ;; (WORD)((TIMERRES*65536)/1000)
TR2 EQU 54 ;; (TIMERRES/1000)
TR3 EQU 56243 ;; (TIMERRES*256*4)/1000
endif
.MODEL SMALL,PASCAL
.DATA
dwLowTickCount dd 0
.CODE
GetLowTickCount PROC FAR USES SI DI
LOCAL wFrac:WORD
; /*--- Disable interrupts; Issue read-back command for counter 0 ---*/
start: mov al, 0C2h ;; read back command
cli
out 43h, al ;; send command to 8254
jmp short $+2 ;; I/O wait
; /*--- Set carry flag to counter 0 OUT pin status ---*/
in al, 40h ;; OUT status is in bit 7
jmp short $+2 ;; I/O wait
shl al, 1 ;; carry = OUT status
; /*--- Set CX to where in interval we are ---*/
in al, 40h ;; read counter low
jmp short $+2 ;; I/O wait
mov cl, al ;; save counter low
in al, 40h ;; read counter high
jmp short $+2 ;; I/O wait
mov ch, al ;; save counter high
jcxz restart ;; restart if counter is zero
rcr cx, 1 ;; combine OUT status w/ counter
not cx ;; change high->low to low->high
; /*--- Convert BIOS ticks to milliseconds (into DI:SI) ---*/
if (?WIN EQ 1)
extrn __0040H:ABS
mov bx, __0040H ;; Windows requires external absolute
else
mov bx, 040h ;; ROM BIOS data area segment
endif
mov es, bx
mov bx, 06Ch ;; offset to timer info
mov ax, TR1
mul WORD PTR es:[bx]
mov wFrac, ax ;; fraction
mov si, dx
mov ax, TR1
mul WORD PTR es:[bx+2]
mov di, dx
add si, ax
adc di, 0
mov ax, TR2
mul WORD PTR es:[bx]
add si, ax
adc di, dx
mov ax, TR2
mul WORD PTR es:[bx+2]
add di, ax
if (TENTHTICK)
; /*--- Get tick count accurate to 1/10000 second ---*/
mov ax, TR3
shr cx, 1
shr cx, 1
shr cx, 1
shr cx, 1
mul cx ;; where in interval
add ax, WORD PTR [wFrac] ;; add fraction
mov ax, si ;; ax = tick count low
adc ax, dx
mov dx, di ;; dx = tick count high
adc dx, 0 ;;
else
; /*--- Get tick count accurate to 1/1000 second ---*/
mov ax, TR3
shr cx, 1
shr cx, 1
mul cx ;; where in interval
add ah, BYTE PTR [wFrac] ;; add fraction low/high
adc dl, BYTE PTR [wFrac+1] ;; ..to get carry
mov ax, si ;; ax = tick count low
adc al, dh ;;
adc ah, 0 ;;
mov dx, di ;; dx = tick count high
adc dx, 0 ;;
endif
; /*--- Assure tick count is equal or advancing ---*/
cmp dx, WORD PTR [dwLowTickCount+2]
ja done
cmp ax, WORD PTR [dwLowTickCount]
jb restart
; /*--- Save last tick count obtained ---*/
done: mov WORD PTR [dwLowTickCount], ax
mov WORD PTR [dwLowTickCount+2], dx
sti
ret
; /*--- Restart procedure ---*/
restart: sti
jmp start
GetLowTickCount ENDP
END